package com.craftyworks.common.web.util;

import java.io.FileNotFoundException;
import java.net.URL;

import javax.servlet.ServletContext;

import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.util.WebUtils;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;

public abstract class LogbackWebConfigurer {

    public static final String CONFIG_LOCATION_PARAM = "logbackConfigLocation";

    public static void initLogging(ServletContext servletContext) {
        String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
        if (location != null) {
            try {
                if (!ResourceUtils.isUrl(location)) {
                    location = SystemPropertyUtils.resolvePlaceholders(location);
                    location = WebUtils.getRealPath(servletContext, location);
                }
                URL url = ResourceUtils.getURL(location);

                servletContext.log("Initializing logback from [" + location + "]");
                
                LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
                JoranConfigurator configurator = new JoranConfigurator();
                configurator.setContext(lc);
                lc.reset(); 
                configurator.doConfigure(url);
            } catch (FileNotFoundException ex) {
                throw new IllegalArgumentException("Invalid 'logbackConfigLocation' parameter: " + ex.getMessage());
            } catch (JoranException e) {
                throw new RuntimeException( "Unexpected error while configuring logback", e );
            }
        }
    }

    public static void shutdownLogging(ServletContext servletContext) {
        servletContext.log("Shutting down logback");
        
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        lc.reset();
        lc.stop();
    }
}
